package com.psytech.app.task.ws;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.Holder;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

import org.apache.log4j.Logger;

import taskmanager.psytech.com.taskmanagerservice._1.Action;
import taskmanager.psytech.com.taskmanagerservice._1.BusinessFault;
import taskmanager.psytech.com.taskmanagerservice._1.BusinessFaultMsg;
import taskmanager.psytech.com.taskmanagerservice._1.Comment;
import taskmanager.psytech.com.taskmanagerservice._1.ObjectFactory;
import taskmanager.psytech.com.taskmanagerservice._1.Task;
import taskmanager.psytech.com.taskmanagerservice._1.TaskManagerService;
import taskmanager.psytech.com.taskmanagerservice._1.TechnicalFault;
import taskmanager.psytech.com.taskmanagerservice._1.TechnicalFaultMsg;
import taskmanager.psytech.com.taskmanagerservice._1.User;

import com.psytech.app.task.service.ServiceLocator.ShortCut;
import com.psytech.app.task.service.exception.BusinessException;
import com.psytech.app.task.service.exception.TechnicalException;

@WebService(name = "TaskManagerService", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1")
@XmlSeeAlso( { ObjectFactory.class })
public class TaskManagerServiceImpl implements TaskManagerService, ShortCut {

	private static final Logger LOG = Logger.getLogger(TaskManagerServiceImpl.class);

	private final ObjectFactory objectFactory = new ObjectFactory();

	@Override
	@WebMethod(operationName = "GetTasks", action = "http://com.psytech.taskmanager/TaskManagerService/1/GetTasks")
	@WebResult(name = "tasks", targetNamespace = "")
	@RequestWrapper(localName = "GetTasks", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.GetTasks")
	@ResponseWrapper(localName = "GetTasksResponse", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.GetTasksResponse")
	public taskmanager.psytech.com.taskmanagerservice._1.GetTasksResponse.Tasks getTasks(@WebParam(name = "user", targetNamespace = "") final User user, @WebParam(name = "task", targetNamespace = "") final Task task)
	throws BusinessFaultMsg, TechnicalFaultMsg {
		try {
			return SL.getTaskManagerService().getTasks(user, task);
		} catch (final Exception exception) {
			if (exception instanceof BusinessException)
				throw getBusinessFaultMsg((BusinessException) exception);
			else if (exception instanceof TechnicalException)
				throw getTechnicalFaultMsg((TechnicalException) exception);
			else {
				LOG.error("Unexpected error", exception);
				final TechnicalFault fault = new TechnicalFault();
				fault.setMessage("Une erreur technique c'est produite lors de la récupération des tâches");
				throw new TechnicalFaultMsg("Unexpected error", fault);// NOPMD
			}
		}
	}

	@Override
	@WebMethod(operationName = "GetUsers", action = "http://com.psytech.taskmanager/TaskManagerService/1/GetUsers")
	@WebResult(name = "users", targetNamespace = "")
	@RequestWrapper(localName = "GetUsers", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.GetUsers")
	@ResponseWrapper(localName = "GetUsersResponse", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.GetUsersResponse")
	public taskmanager.psytech.com.taskmanagerservice._1.GetUsersResponse.Users getUsers(@WebParam(name = "user", targetNamespace = "") final User user) throws BusinessFaultMsg, TechnicalFaultMsg {
		try {
			return SL.getTaskManagerService().getUsers(user);
		} catch (final Exception exception) {
			if (exception instanceof BusinessException)
				throw getBusinessFaultMsg((BusinessException) exception);
			else if (exception instanceof TechnicalException)
				throw getTechnicalFaultMsg((TechnicalException) exception);
			else {
				LOG.error("Unexpected error", exception);
				final TechnicalFault fault = new TechnicalFault();
				fault.setMessage("Une erreur technique c'est produite lors de la récupération des utilisateurs");
				throw new TechnicalFaultMsg("Unexpected error", fault);// NOPMD
			}
		}
	}

	@Override
	@WebMethod(operationName = "ManageTask", action = "http://com.psytech.taskmanager/TaskManagerService/1/ManageTask")
	@RequestWrapper(localName = "ManageTask", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.ManageTask")
	@ResponseWrapper(localName = "ManageTaskResponse", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.ManageTaskResponse")
	public void manageTask(@WebParam(name = "task", targetNamespace = "", mode = WebParam.Mode.INOUT) final Holder<Task> task,
			@WebParam(name = "action", targetNamespace = "") final Action action) throws BusinessFaultMsg, TechnicalFaultMsg {
		try {
			if (action.compareTo(Action.DELETE) == 0) {
				LOG.debug("Demande de suppression d'une t�che");
				SL.getTaskManagerService().deleteTask(task.value);
			} else {
				LOG.debug("Demande d'une creation/mise � jour");
				task.value = SL.getTaskManagerService().saveTask(task.value);
			}
		} catch (final Exception exception) {
			if (exception instanceof BusinessException)
				throw getBusinessFaultMsg((BusinessException) exception);
			else if (exception instanceof TechnicalException)
				throw getTechnicalFaultMsg((TechnicalException) exception);
			else {
				LOG.error("Unexpected error", exception);
				final TechnicalFault fault = new TechnicalFault();
				fault.setMessage("Une erreur technique c'est produite lors de la mise à jour d'une tâche");
				throw new TechnicalFaultMsg("Unexpected error", fault);// NOPMD
			}
		}

	}

	@Override
	@WebMethod(operationName = "ManageUser", action = "http://com.psytech.taskmanager/TaskManagerService/1/ManageUser")
	@RequestWrapper(localName = "ManageUser", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.ManageUser")
	@ResponseWrapper(localName = "ManageUserResponse", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.ManageUserResponse")
	public void manageUser(@WebParam(name = "user", targetNamespace = "", mode = WebParam.Mode.INOUT) final Holder<User> user,
			@WebParam(name = "action", targetNamespace = "") final Action action) throws BusinessFaultMsg, TechnicalFaultMsg {
		try {
			if (action.compareTo(Action.DELETE) != 0)
				user.value = SL.getTaskManagerService().saveUser(user.value);
			else
				SL.getTaskManagerService().deleteUser(user.value);
		} catch (final Exception exception) {
			if (exception instanceof BusinessException)
				throw getBusinessFaultMsg((BusinessException) exception);
			else if (exception instanceof TechnicalException)
				throw getTechnicalFaultMsg((TechnicalException) exception);
			else {
				LOG.error("Unexpected error", exception);
				final TechnicalFault fault = new TechnicalFault();
				fault.setMessage("Une erreur technique c'est produite lors de la mise à jour d'un utilisateur");
				throw new TechnicalFaultMsg("Unexpected error", fault);// NOPMD
			}
		}
	}

	@Override
	@WebMethod(operationName = "GetComments", action = "http://com.psytech.taskmanager/TaskManagerService/1/GetComments")
	@WebResult(name = "comments", targetNamespace = "")
	@RequestWrapper(localName = "GetComments", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.GetComments")
	@ResponseWrapper(localName = "GetCommentsResponse", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.GetCommentsResponse")
	public taskmanager.psytech.com.taskmanagerservice._1.GetCommentsResponse.Comments getComments(@WebParam(name = "task", targetNamespace = "") final Task task) throws BusinessFaultMsg, TechnicalFaultMsg {
		try {
			return SL.getTaskManagerService().getComments(task);
		} catch (final Exception exception) {
			if (exception instanceof BusinessException)
				throw getBusinessFaultMsg((BusinessException) exception);
			else if (exception instanceof TechnicalException)
				throw getTechnicalFaultMsg((TechnicalException) exception);
			else {
				LOG.error("Unexpected error", exception);
				final TechnicalFault fault = new TechnicalFault();
				fault.setMessage("Une erreur technique c'est produite lors de la récupération des commentaires");
				throw new TechnicalFaultMsg("Unexpected error", fault);// NOPMD
			}
		}
	}

	@Override
	@WebMethod(operationName = "ManageComment", action = "http://com.psytech.taskmanager/TaskManagerService/1/ManageComment")
	@RequestWrapper(localName = "ManageComment", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.ManageComment")
	@ResponseWrapper(localName = "ManageCommentResponse", targetNamespace = "http://com.psytech.taskmanager/TaskManagerService/1", className = "taskmanager.psytech.com.taskmanagerservice._1.ManageCommentResponse")
	public void manageComment(@WebParam(name = "comment", targetNamespace = "", mode = WebParam.Mode.INOUT) final Holder<Comment> comment,
			@WebParam(name = "action", targetNamespace = "") final Action action) throws BusinessFaultMsg, TechnicalFaultMsg {
		try {
			if (action.compareTo(Action.DELETE) == 0)
				SL.getTaskManagerService().deleteComment(comment.value);
			else
				comment.value = SL.getTaskManagerService().createComment(comment.value);
		} catch (final Exception exception) {
			if (exception instanceof BusinessException)
				throw getBusinessFaultMsg((BusinessException) exception);
			else if (exception instanceof TechnicalException)
				throw getTechnicalFaultMsg((TechnicalException) exception);
			else {
				LOG.error("Unexpected error", exception);
				final TechnicalFault fault = new TechnicalFault();
				fault.setMessage("Une erreur technique c'est produite lors de la mise à jour d'un commentaire");
				throw new TechnicalFaultMsg("Unexpected error", fault);// NOPMD
			}
		}

	}

	private TechnicalFaultMsg getTechnicalFaultMsg(final TechnicalException technicalException) {
		final TechnicalFault fault = new ObjectFactory().createTechnicalFault();
		fault.setCode(technicalException.getCode());
		fault.setMessage(technicalException.getMessage());
		return new TechnicalFaultMsg("Error", fault);
	}

	private BusinessFaultMsg getBusinessFaultMsg(final BusinessException busisnessException) {
		final BusinessFault fault = new ObjectFactory().createBusinessFault();
		fault.setCode(busisnessException.getCode());
		fault.setMessage(busisnessException.getMessage());
		return new BusinessFaultMsg("Error", fault);
	}

}
